package utils;

import android.text.TextUtils;
import android.util.Log;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.Closeable;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.net.FileNameMap;
import java.net.URLConnection;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Locale;

/**
 * @author litingwei
 * Created on 2017年3月17日 下午4:50:04
 */
public class FileUtils {
	public static final String TAG = FileUtils.class.getCanonicalName();
	
	public static final long ONE_K = 1024L;
	
	public static final long ONE_M = 1024 * ONE_K;
	
	public static final long ONE_G = 1024 * ONE_M;

	private static final HashSet<String> PREFIX_VIDEO = new HashSet<>();
	private static final HashSet<String> PREFIX_IMAGE = new HashSet<>();
	private static final HashSet<String> PREFIX_PDF = new HashSet<>();
	private static final HashSet<String> PREFIX_MS_WORD = new HashSet<>();
	private static final HashSet<String> PREFIX_MS_EXCEL = new HashSet<>();
	private static final HashSet<String> PREFIX_MS_PPT = new HashSet<>();
	static {
		PREFIX_VIDEO.add("video/mp4");
		PREFIX_IMAGE.add("image/jpeg");
		PREFIX_IMAGE.add("application/x-jpg");
		PREFIX_IMAGE.add("image/png");
		PREFIX_IMAGE.add("application/x-png");
		PREFIX_PDF.add("application/pdf");
		PREFIX_MS_WORD.add("application/msword");
		PREFIX_MS_WORD.add("application/vnd.openxmlformats-officedocument.wordprocessingml.document");
        PREFIX_MS_EXCEL.add("application/vnd.ms-excel");
        PREFIX_MS_EXCEL.add("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
        PREFIX_MS_PPT.add("application/vnd.ms-powerpoint");
        PREFIX_MS_PPT.add("application/vnd.openxmlformats-officedocument.presentationml.presentation");
	}

	/**
	 * 通过文件名获取 MimeType
	 * @param fileName 文件名
	 * @return mimeType
	 */
	public static String getMimeType(String fileName) {
		FileNameMap fileNameMap = URLConnection.getFileNameMap();
		return fileNameMap.getContentTypeFor(fileName);
	}

	/**
	 * 文件是否视频文件
	 * @param fileName 文件名
	 */
	public static boolean isVideoFile(String fileName) {
		String mimeType = getMimeType(fileName);
		return !TextUtils.isEmpty(mimeType) && PREFIX_VIDEO.contains(mimeType);
	}

	/**
	 * 文件是否图片文件
	 * @param fileName 文件名
	 */
	public static boolean isImageFile(String fileName) {
		String mimeType = getMimeType(fileName);
		return !TextUtils.isEmpty(mimeType) && PREFIX_IMAGE.contains(mimeType);
	}

    public static boolean isPdfFile(String fileName) {
        String mimeType = getMimeType(fileName);
        return !TextUtils.isEmpty(mimeType) && PREFIX_PDF.contains(mimeType);
    }

	public static boolean isWordFile(String fileName) {
        String mimeType = getMimeType(fileName);
        return !TextUtils.isEmpty(mimeType) && PREFIX_MS_WORD.contains(mimeType);
    }

    public static boolean isExcelFile(String fileName) {
        String mimeType = getMimeType(fileName);
        return !TextUtils.isEmpty(mimeType) && PREFIX_MS_EXCEL.contains(mimeType);
    }

    public static boolean isPptFile(String fileName) {
        String mimeType = getMimeType(fileName);
        return !TextUtils.isEmpty(mimeType) && PREFIX_MS_PPT.contains(mimeType);
    }
	
	/**
	 * 保存String列表到文件
	 * @param file
	 * @param lineList
	 * @return
	 */
	public static boolean exportCsv(File file, List<String> lineList) {
		if (file.isDirectory()) {
			return false;
		}
		if (!file.getParentFile().exists()) {
			if (!file.getParentFile().mkdirs()) {
				return false;
			}
		}
		FileOutputStream fos = null;
		BufferedWriter bw = null;
		try {
			fos = new FileOutputStream(file);
			bw = new BufferedWriter(new OutputStreamWriter(fos));
			for (String line : lineList) {
				bw.append(line).append("\r\n");
			}
			bw.flush();
			fos.flush();
			return true;
		} catch (IOException e) {
			Log.e(TAG, e.getMessage());
			return false;
		} finally {
			closeIO(bw);
			closeIO(fos);
		}
	}
	
	/**
	 * 读取文件到String列表
	 * @param file
	 * @return
	 */
	public static List<String> importCsv(File file) {
		if (!file.exists() || file.isDirectory()) {
			return null;
		}
		FileInputStream fis = null;
		BufferedReader br = null;
		try {
			fis = new FileInputStream(file);
			br = new BufferedReader(new InputStreamReader(fis));
			List<String> list = new ArrayList<String>();
			String line = null;
			while ((line = br.readLine()) != null) {
				list.add(line);
			}
			return list;
		} catch (IOException e) {
			Log.e(TAG, e.getMessage());
			return null;
		} finally {
			closeIO(br);
			closeIO(fis);
		}
	}
	
	/**
	 * 获取文件大小
	 * @param file
	 * @return
	 */
	public static String getFileSize(File file) {
		if (file == null) {
            return "0B";
        }
		long length = file.length();
		return getSizeByLength(length);
	}

	public static String getSizeByLength(long length) {
        if (length < ONE_K) {
            return String.format(Locale.CHINA, "%dB", length);
        } else if (length < ONE_M) {
            return String.format(Locale.CHINA, "%.2fKB", ((double)length) / ONE_K);
        } else if (length < ONE_G) {
            return String.format(Locale.CHINA, "%.2fMB", ((double)length) / ONE_M);
        } else {
            return String.format(Locale.CHINA, "%.2fGB", ((double)length) / ONE_G);
        }
    }

    public static long converSize2Length(String size) {
		String[] numString = size.split("[a-z|A-Z]");
		if (!TextUtils.isEmpty(numString[0])) {
			double num = 0;
			try {
				num = Double.valueOf(numString[0]);
			} catch (Exception e) {
				e.printStackTrace();
			}
			String unit = size.substring(numString[0].length());
			if (TextUtils.equals("", unit) || TextUtils.equals("b", unit.toLowerCase())) {
				return Math.round(num);
			} else if (TextUtils.equals("k", unit) || TextUtils.equals("kb", unit.toLowerCase())) {
			    return Math.round(num * ONE_K);
            } else if (TextUtils.equals("m", unit) || TextUtils.equals("mb", unit.toLowerCase())) {
                return Math.round(num * ONE_M);
            } else if (TextUtils.equals("g", unit) || TextUtils.equals("gb", unit.toLowerCase())) {
                return Math.round(num * ONE_G);
            }
		}
		return 0;
	}
	
	/**
	 * 对文件进行md5加密
	 * @param checkFile 要加密的文件
	 * @return md5值(32位)
	 */
	public static String md5Hex(File checkFile) {
		if (!checkFile.exists()) {
            return null;
        }
		try {
			InputStream is = new FileInputStream(checkFile);
			return md5Hex(is);
		} catch (FileNotFoundException e) {
			Log.e(TAG, e.getMessage());
		}
		return null;
	}
	
	/**
	 * 对输入流进行md5加密
	 * @param data 要加密的输入流
	 * @return md5值(32位)
	 */
	public static String md5Hex(InputStream data) {
		MessageDigest md5;
		byte[] buffer = new byte[8192];
		int len = 0;
		try {
			md5 = MessageDigest.getInstance("MD5");
			while ((len = data.read(buffer)) != -1) {
				md5.update(buffer, 0, len);
			}
			return scooper.cn.sc_base.StringUtils.toHex(md5.digest());
		} catch (NoSuchAlgorithmException e) {
			Log.e(TAG, e.getMessage());
		} catch (IOException e) {
			Log.e(TAG, e.getMessage());
		} finally {
			closeIO(data);
		}
		return null;
	}

	/**
	 * 移动文件
	 * @param srcFile
	 * @param dstFile
	 * @return
	 */
	public static boolean copyFile(File srcFile, File dstFile) {
		FileInputStream fis = null;
		FileOutputStream fos = null;
		if (!srcFile.exists()) {
			return false;
		}
		try {
			fis = new FileInputStream(srcFile);
			fos = new FileOutputStream(dstFile);
			byte[] buffer = new byte[128 * 1024];
			int len;
			while ((len = fis.read(buffer)) != -1) {
				fos.write(buffer, 0, len);
			}
			fos.flush();
			return true;
		} catch (IOException e) {
			Log.e(TAG, e.getMessage());
			return false;
		}finally {
			closeIO(fis);
			closeIO(fos);
		}
	}

	/**
	 * 移动文件
	 * @param is
	 * @param dstFile
	 * @return
	 */
	public static boolean copyFile(InputStream is, File dstFile) {
		FileOutputStream fos = null;
		if (is == null) {
			return false;
		}
		try {
			fos = new FileOutputStream(dstFile);
			byte[] buffer = new byte[128 * 1024];
			int len;
			while ((len = is.read(buffer)) != -1) {
				fos.write(buffer, 0, len);
			}
			fos.flush();
			return true;
		} catch (IOException e) {
			Log.e(TAG, e.getMessage());
			return false;
		}finally {
			closeIO(is);
			closeIO(fos);
		}
	}

    /**
     * 释放资源。
     * 
     * @param c
     *            将关闭的资源
     */
    public static final void closeIO(Closeable c) {
        if (c != null) {
            try {
                c.close();
            } catch (IOException e) {
				Log.e(TAG, e.getMessage());
            }
        }
    }

}
